from scapy.all import sniff, IP, UDP
from scapy.contrib.gtp import GTP_U_Header
import paramiko
import time
import requests

def packet_callback(packet):
    host = '172.16.10.254'
    port = 22
    username = 'admin'
    password = 'gsta@passw0rd'
    openCommands = ['system-view', 'security-policy ip', 'rule name wifictl', 'source-ip-host 172.16.10.16']  # 命令链
    closeCommands = ['system-view', 'security-policy ip', 'rule name wifictl', 'undo source-ip-host 172.16.10.16']
    # 检查数据包是否包含IP、UDP和GTP头部
    if IP in packet and UDP in packet and GTP_U_Header in packet:
        # 从GTP载荷中提取内部的IP数据包
        inner_packet = packet[GTP_U_Header].payload
        if IP in inner_packet:
            src_ip = inner_packet[IP].src
            dst_ip = inner_packet[IP].dst
            print(f"Inner IP src: {src_ip}")
            print(f"Inner IP dst: {dst_ip}")
            # 这个加入请求区块链的api，根据返回结果进行控制
            status = 0
            if src_ip.startswith('12.1.1.'):
                response = send_to_api(id)
                if(response['errorCode'] == 0 and status == 1):
                    ssh_command(host, port, username, password, openCommands)
                    status = 0
                elif(response['errorCode'] == 1 and status == 0):
                    ssh_command(host, port, username, password, closeCommands)
                    status = 1


# 过滤GTP数据包（通常使用UDP端口2152）
def ssh_command(host, port, username, password, commands):
    client = paramiko.SSHClient()
    # 添加已知的主机密钥
    client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    client.connect(host, port, username, password)

    # 创建一个持续的 shell 会话
    shell = client.invoke_shell()

    def execute(command):
        shell.send(command + "\n")
        time.sleep(2)  # 等待命令执行
        output = shell.recv(10000).decode()  # 调整缓冲区大小根据需要
        print(output)

    for command in commands:
        execute(command)

    client.close()

def send_to_api(id):
    # 设定API的URL
    api_url = "172.16.10.16:30002/getVerifyCredentialResult"
    
    # 发送POST请求到API
    response = requests.post(api_url, data={
        'id' : id
    })
    
    # 打印API响应，可根据需要调整
    print(response.text)
if __name__ == "__main__":
    # 示例参数，你应该用实际的值替换它们
    sniff(prn=packet_callback, filter="udp port 2152", store=0)


